﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using WebSite.App_Data;
using WebSite.App_Code;
using System.Xml;
using System.Collections.Specialized;

namespace WebSite.App_Code
{
    #region Item.PayDetail

    public class PayDetailItem
    {
        public PayDetailItem()
        {
            Detail = new wf_PayDetail();
            AccountShow = String.Empty;
        }

        public wf_PayDetail Detail { get; set; }

        public String AccountShow { get; set; }
    }

    #endregion

    #region Item.PayQueryFilter

    public class PayQueryFilterItem
    {
        public PayQueryFilterItem()
        {
            this.AccountCode = string.Empty;
            this.Amount = string.Empty;
            this.CategoryAmount = string.Empty;
            this.Comment = string.Empty;
            this.DepartmentID = string.Empty;
            this.PayCategory = string.Empty;
            this.PayDateBegin = string.Empty;
            this.PayDateEnd = string.Empty;
            this.PayNo = string.Empty;
            this.PayStatus = string.Empty;
            this.PjCode = string.Empty;
            this.PjName = string.Empty;
            this.PjPic = string.Empty;
            this.Rem = string.Empty;
        }

        /// <summary> 经费审核结算单的编号，支持模糊查询 </summary>
        public string PayNo { get; set; }

        /// <summary> 经费审核结算单的结算日期（起）</summary>
        public string PayDateBegin { get; set; }

        /// <summary> 经费审核结算单的结算日期（止）</summary>
        public string PayDateEnd { get; set; }

        /// <summary> 结算单位</summary>
        public string DepartmentID { get; set; }

        /// <summary> 项目负责人</summary>
        public string PjPic { get; set; }

        /// <summary> 项目名称</summary>
        public string PjName { get; set; }

        /// <summary> 项目代号</summary>
        public string PjCode { get; set; }

        /// <summary> 会计科目</summary>
        public string AccountCode { get; set; }

        /// <summary> 金额</summary>
        public string Amount { get; set; }

        /// <summary> 分类</summary>
        public string PayCategory { get; set; }

        /// <summary> 分类金额</summary>
        public string CategoryAmount { get; set; }

        /// <summary> 摘要</summary>
        public string Comment { get; set; }

        /// <summary> 状态</summary>
        public string PayStatus { get; set; }

        /// <summary> 备注 </summary>
        public string Rem { get; set; }

    }

    #endregion
}

namespace WebSite.Models
{
    #region Model.Pay

    public class PayModel : BaseModel
    {
        public PayModel()
        {
            this.DS_Department = new List<SelectListItem>();
            this.DS_Pay = new wf_Pay();
            this.DS_PayDetail = new List<PayDetailItem>();
            this.DS_PayType = new List<SelectListItem>();
            this.New_PayDetail = new wf_PayDetail();

            this.DS_AC_Budget = new List<vw_Budget>();
            this.DS_AC_Asset = new List<md_AssetSubject>();
            this.CM_SAD = new SelAccountDetailModel();
        }

        public List<vw_Budget> DS_AC_Budget { get; set; }

        public List<md_AssetSubject> DS_AC_Asset { get; set; }

        public List<PayDetailItem> DS_PayDetail { get; set; }

        public wf_PayDetail New_PayDetail { get; set; }

        public wf_Pay DS_Pay { get; set; }
        
        public List<SelectListItem> DS_Department { get; set; }

        public List<SelectListItem> DS_PayType { get; set; }

        public SelAccountDetailModel CM_SAD { get; set; }

        public virtual void Init(string ID)
        {
            DBDataContext DB = new DBDataContext();

            DB.Connection.Open();

            IEnumerable<vw_Budget> ieBudget = (from x in DB.vw_Budgets
                                               from y in DB.list_Years
                                               where x.BudgetStatus == ((int)L_BudgetStatus.Use).ToString()
                                               where x.BudgetYear == y.ID
                                               where y.IsUsed
                                               select x);
            if (ieBudget.Any())
                this.DS_AC_Budget = ieBudget.ToList();

            IEnumerable<md_AssetSubject> ieAsset = from x in DB.md_AssetSubjects
                                                   where x.IsActive
                                                   select x;
            if (ieAsset.Any())
                this.DS_AC_Asset = ieAsset.ToList();

            IEnumerable<SelectListItem> ieDepartment = (from x in DB.md_Departments
                                                        where x.Status
                                                  select new SelectListItem()
                                                  {
                                                      Text = x.DepartmentName,
                                                      Value = x.Guid
                                                  }).Distinct();
            if (ieDepartment.Any())
                this.DS_Department = ieDepartment.ToList();
            this.DS_Department.Insert(0, new SelectListItem());

            IEnumerable<SelectListItem> iePayType = (from x in DB.list_PayTypes
                                                     select new SelectListItem()
                                                     {
                                                         Text = x.Name,
                                                         Value = x.ID
                                                     }).Distinct();
            if (iePayType.Any())
                this.DS_PayType = iePayType.ToList();
            //this.DS_PayType.Insert(0, new SelectListItem());

            this.DS_Pay.Guid = ID;

            if (this.DS_PayDetail.Count == 0)
            {
                this.DS_Pay.PayDate = DateTime.Now.ToString("yyyy-MM-dd");
                this.DS_PayDetail.Add(new PayDetailItem());
            }

            DB.Connection.Close();
        }

        public String Save()
        {
            DBDataContext DB = new DBDataContext();

            DB.Connection.Open();

            DB.Transaction = DB.Connection.BeginTransaction();

            try
            {
                IEnumerable<wf_Pay> iePay = from x in DB.wf_Pays where x.Guid == this.DS_Pay.Guid select x;

                if (iePay.Any())
                {
                    wf_Pay oPay = iePay.First();
                    oPay.AttachmentNum = this.DS_Pay.AttachmentNum;
                    oPay.BillNum = this.DS_Pay.BillNum;
                    oPay.DepartmentGuid = this.DS_Pay.DepartmentGuid;
                    oPay.PayDate = this.DS_Pay.PayDate;
                    oPay.Rem = this.DS_Pay.Rem;
                }
                else
                {
                    String PayGuid = Guid.NewGuid().ToString();

                    this.DS_Pay.PayStatus = ((int)L_PayStatus.Save).ToString();
                    this.DS_Pay.SN = "T" + GetTmpIndex(ref DB).ToString("D7");
                    this.DS_Pay.Guid = PayGuid;

                    DB.wf_Pays.InsertOnSubmit(this.DS_Pay);

                    for (int i = 0; i < this.DS_PayDetail.Count; i++)
                    {
                        this.DS_PayDetail[i].Detail.ParentGuid = PayGuid;
                        this.DS_PayDetail[i].Detail.Guid = Guid.NewGuid().ToString();
                        DB.wf_PayDetails.InsertOnSubmit(this.DS_PayDetail[i].Detail);
                    }
                }

                DB.SubmitChanges();

                DB.Transaction.Commit();
            }
            catch (Exception Ex)
            {
                DB.Transaction.Rollback();

                CommonItem.WirteErrorLog(L_LogType.P_Save, Ex, String.Empty, this.U);

                return "保存失败: " + Ex.Message;
            }
            finally
            {
                DB.Connection.Close();
                DB = null;
            }

            return "保存成功!";
        }

        public String Submit()
        {
            DBDataContext DB = new DBDataContext();

            DB.Connection.Open();

            DB.Transaction = DB.Connection.BeginTransaction();

            try
            {
                IEnumerable<wf_Pay> iePay = from x in DB.wf_Pays where x.Guid == this.DS_Pay.Guid select x;

                if (iePay.Any())
                {
                    wf_Pay oPay = iePay.First();
                    oPay.AttachmentNum = this.DS_Pay.AttachmentNum;
                    oPay.BillNum = this.DS_Pay.BillNum;
                    oPay.DepartmentGuid = this.DS_Pay.DepartmentGuid;
                    oPay.PayDate = this.DS_Pay.PayDate;
                    oPay.Rem = this.DS_Pay.Rem;
                    oPay.PayStatus = ((int)L_PayStatus.Pending).ToString();
                    oPay.SN = GetIndex(ref DB).ToString("D7");

                    this.DS_Pay.SN = oPay.SN;
                    this.DS_Pay.PayStatus = oPay.PayStatus;
                }
                else
                {
                    String PayGuid = Guid.NewGuid().ToString();

                    this.DS_Pay.PayStatus = ((int)L_PayStatus.Pending).ToString();
                    this.DS_Pay.SN = GetIndex(ref DB).ToString("D7");
                    this.DS_Pay.Guid = PayGuid;

                    DB.wf_Pays.InsertOnSubmit(this.DS_Pay);

                    for (int i = 0; i < this.DS_PayDetail.Count; i++)
                    {
                        this.DS_PayDetail[i].Detail.ParentGuid = PayGuid;
                        this.DS_PayDetail[i].Detail.Guid = Guid.NewGuid().ToString();
                        DB.wf_PayDetails.InsertOnSubmit(this.DS_PayDetail[i].Detail);
                    }
                }
                
                CommonItem.WirteLog(DB, L_LogType.P_Submit, string.Empty, this.PostingID, string.Empty, U);

                DB.SubmitChanges();

                DB.Transaction.Commit();
            }
            catch (Exception Ex)
            {
                DB.Transaction.Rollback();

                CommonItem.WirteErrorLog(L_LogType.P_Submit, Ex, String.Empty, this.U);

                return "提交失败: " + Ex.Message;
            }
            finally
            {
                DB.Connection.Close();
                DB = null;
            }

            return "提交成功!";
        }

        public int GetTmpIndex(ref DBDataContext DB)
        {
            int rv = 0;

            IEnumerable<md_Index> ieIndex = from x in DB.md_Indexes
                                            where x.Type == 2
                                            select x;

            if (ieIndex.Any())
            {
                md_Index oIndex = ieIndex.First();
                oIndex.No += 1;
                rv = oIndex.No;
            }
            else
            {
                DB.md_Indexes.InsertOnSubmit(new md_Index()
                {
                    No = 0,
                    Type = 2
                });
            }
            DB.SubmitChanges();

            return rv;
        }

        public int GetIndex(ref DBDataContext DB)
        {
            int rv = 0;

            IEnumerable<md_Index> ieIndex = from x in DB.md_Indexes
                                            where x.Type == 1
                                            select x;

            if (ieIndex.Any())
            {
                md_Index oIndex = ieIndex.First();
                oIndex.No += 1;
                rv = oIndex.No;
            }
            else
            {
                DB.md_Indexes.InsertOnSubmit(new md_Index()
                {
                    No = 0,
                    Type = 1
                });
            }
            DB.SubmitChanges();

            return rv;
        }
    }

    #endregion

    #region Model.SelAccountDetail

    public class SelAccountDetailModel
    {
        public SelAccountDetailModel()
        {
            this.Type = L_AccountType.NA;
            this.B = new vw_Budget();
            this.B_Item = new List<vw_BudgetItem>();
            this.AS = new md_AssetSubject();
            this.AS_Detail = new List<md_AssetSubjectDetail>();
        }


        public L_AccountType Type { get; set; }

        public vw_Budget B { get; set; }

        public List<vw_BudgetItem> B_Item { get; set; }

        public md_AssetSubject AS { get; set; }

        public List<md_AssetSubjectDetail> AS_Detail { get; set; }
    }

    #endregion

    #region Model.PayQuery

    public class PayQueryModel : BaseModel
    {
        public List<SelectListItem> DS_Department { get; set; }

        public List<SelectListItem> DS_AS { get; set; }

        public List<SelectListItem> DS_PayC { get; set; }

        public List<SelectListItem> DS_PayS { get; set; }

        public PayQueryFilterItem QueryFilter { get; set; }

        public List<vw_Pay> QueryResult { get; set; }

        public PayQueryModel()
        {
            this.DS_Department = new List<SelectListItem>();
            this.DS_AS = new List<SelectListItem>();
            this.DS_PayC = new List<SelectListItem>();
            this.DS_PayS = new List<SelectListItem>();
            this.QueryFilter = new PayQueryFilterItem();
            this.QueryResult = new List<vw_Pay>();
        }

        public virtual void Init(L_Page PageID)
        {
            DBDataContext DB = new DBDataContext();

            DB.Connection.Open();

            IEnumerable<SelectListItem> ieAsset = from x in DB.md_AssetSubjects
                                                  where x.IsActive
                                                  select new SelectListItem()
                                                  {
                                                      Text = x.Name,
                                                      Value = x.No
                                                  };
            if (ieAsset.Any())
                this.DS_AS = ieAsset.ToList();
            this.DS_AS.Insert(0, new SelectListItem());

            IEnumerable<SelectListItem> ieDepartment = (from x in DB.md_Departments
                                                        where x.Status
                                                        select new SelectListItem()
                                                        {
                                                            Text = x.DepartmentName,
                                                            Value = x.Guid
                                                        }).Distinct();
            if (ieDepartment.Any())
                this.DS_Department = ieDepartment.ToList();
            this.DS_Department.Insert(0, new SelectListItem());

            IEnumerable<SelectListItem> iePayC   = (from x in DB.list_ProjectCategories
                                                     select new SelectListItem()
                                                     {
                                                         Text = x.Name,
                                                         Value = x.ID
                                                     }).Distinct();
            if (iePayC.Any())
                this.DS_PayC = iePayC.ToList();
            this.DS_PayC.Insert(0, new SelectListItem());

            IEnumerable<SelectListItem> iePayS = (from x in DB.list_PayStatus
                                                  select new SelectListItem()
                                                  {
                                                      Text = x.Name,
                                                      Value = x.Status
                                                  }).Distinct();
            if (iePayS.Any())
                this.DS_PayS = iePayS.ToList();
            this.DS_PayS.Insert(0, new SelectListItem());

            DB.Connection.Close();
        }

        public void Query()
        {
            DBDataContext DB = new DBDataContext();

            DB.Connection.Open();

            IEnumerable<vw_Pay> ieTmp = from x in DB.vw_Pays
                                        where (this.QueryFilter.PayNo == string.Empty || this.QueryFilter.PayNo == x.SN)
                                        //where (this.QueryFilter.PayDateBegin == string.Empty || Convert.ToDateTime(this.QueryFilter.PayDateBegin) < Convert.ToDateTime(x.PayDate))
                                        //where (this.QueryFilter.PayDateEnd == string.Empty || Convert.ToDateTime(this.QueryFilter.PayDateEnd) > Convert.ToDateTime(x.PayDate))
                                        //where (this.QueryFilter.DepartmentID == string.Empty || this.QueryFilter.DepartmentID == x.DepartmentGuid)
                                        //where (this.QueryFilter.PjPic == string.Empty || this.QueryFilter.PjPic == x.SN)
                                        //where (this.QueryFilter.PjName == string.Empty || this.QueryFilter.PayNo == x.SN)
                                        //where (this.QueryFilter.PjCode == string.Empty || this.QueryFilter.PayNo == x.SN)
                                        //where (this.QueryFilter.Amount == string.Empty || this.QueryFilter.PayNo == x.SN)
                                        //where (this.QueryFilter.PayCategory == string.Empty || this.QueryFilter.PayNo == x.SN)
                                        //where (this.QueryFilter.CategoryAmount == string.Empty || this.QueryFilter.PayNo == x.SN)
                                        //where (this.QueryFilter.Comment == string.Empty || this.QueryFilter.PayNo == x.SN)
                                        //where (this.QueryFilter.PayStatus == string.Empty || this.QueryFilter.PayNo == x.SN)
                                        //where (this.QueryFilter.Rem == string.Empty || this.QueryFilter.PayNo == x.SN)                                        
                                        select x;

            if (ieTmp.Any())
                this.QueryResult = ieTmp.ToList();

            DB.Connection.Close();

        }
    }

    #endregion
}
